Composite Command

계좌 A-B 사이의 송금 처리
1. 계좌 A에서 $X 만큼 출금
2. 계좌 B에 $X 만큼 입금

위와 같은 두 커멘드를 호출하는 대신에 하나의 "계좌 이체” 커멘드를 감싸서 처리하는 방식이
컴포지트 커멘드 패턴에서 지향하는 바이다.
struct CompositeBankAccountCommand: vector<BankAccountCommand>, Command{
CompositeBankAccountCommand(const initializer_list<value_type>& items): vector<BankAccountCommand>(items) {}
void call() override {
for(auto& cmd: *this) cmd.call();
}
void undo() override { // Command !
for(auto it=rbegin(); it!=rend(); ++it) it->undo();
}
};
//
struct MoneyTransferCommand: CompositeBankAccountCommand{
MoneyTransferCommand(BankAccount& from, BankAccount& to, int amount): CompositeBankAccountCommand{
BankAccountCommand{from, BankAccountCommand::withdraw, amount}, BankAccountCommand{to, BankAccountCommnad::deposit, amount}
} {}
};
단, 출금이 실패하였을 경우, 입금을 실행되지 않도록
전체 명령 사슬이 취소되어야 한다.
void call() override {
bool ok=true;
for(auto& cmd: *this){
if(ok){
cmd.call();
ok=cmd.succeeded;
} else {
cmd.succeeded=false;
}
}
}